AddEventCommandHandler.execute   B
last analyzed

Complexity

Conditions 5

Size

Total Lines 47
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 33
dl 0
loc 47
c 0
b 0
f 0
rs 8.6213
cc 5
1
import { CommandHandler } from '@nestjs/cqrs';
2
import { Inject } from '@nestjs/common';
3
import { AddEventCommand } from './AddEventCommand';
4
import { ITaskRepository } from 'src/Domain/Task/Repository/ITaskRepository';
5
import { IProjectRepository } from 'src/Domain/Project/Repository/IProjectRepository';
6
import { IEventRepository } from 'src/Domain/FairCalendar/Repository/IEventRepository';
7
import { IsMaximumTimeSpentReached } from 'src/Domain/FairCalendar/Specification/IsMaximumTimeSpentReached';
8
import { Event, EventType } from 'src/Domain/FairCalendar/Event.entity';
9
import { IDateUtils } from 'src/Application/IDateUtils';
10
import { ProjectOrTaskMissingException } from 'src/Domain/FairCalendar/Exception/ProjectOrTaskMissingException';
11
import { AbstractProjectAndTaskGetter } from './AbstractProjectAndTaskGetter';
12
import { NoDateDuringThisPeriodException } from 'src/Domain/FairCalendar/Exception/NoDateDuringThisPeriodException';
13
import { AddEventsView } from '../View/AddEventsView';
14
import { MaximumEventReachedException } from 'src/Domain/FairCalendar/Exception/MaximumEventReachedException';
15
16
@CommandHandler(AddEventCommand)
17
export class AddEventCommandHandler extends AbstractProjectAndTaskGetter {
18
  constructor(
19
    @Inject('ITaskRepository') taskRepository: ITaskRepository,
20
    @Inject('IProjectRepository') projectRepository: IProjectRepository,
21
    @Inject('IEventRepository')
22
    private readonly eventRepository: IEventRepository,
23
    @Inject('IDateUtils')
24
    private readonly dateUtils: IDateUtils,
25
    private readonly isMaximumTimeSpentReached: IsMaximumTimeSpentReached
26
  ) {
27
    super(taskRepository, projectRepository);
28
  }
29
30
  public async execute(command: AddEventCommand): Promise<AddEventsView> {
31
    const {
32
      type,
33
      startDate,
34
      endDate,
35
      projectId,
36
      taskId,
37
      summary,
38
      time,
39
      user
40
    } = command;
41
    const errors: string[] = [];
42
43
    if (type === EventType.MISSION && (!projectId || !taskId)) {
44
      throw new ProjectOrTaskMissingException();
45
    }
46
47
    const days = this.getDays(startDate, endDate);
48
    const [project, task] = await Promise.all([
49
      this.getProject(projectId),
50
      this.getTask(taskId)
51
    ]);
52
53
    const savePromises: Promise<any>[] = [];
54
55
    for (const day of days) {
56
      const date = this.dateUtils.format(day, 'y-MM-dd');
57
      const event = new Event(type, user, time, date, project, task, summary);
58
59
      if (
60
        true === (await this.isMaximumTimeSpentReached.isSatisfiedBy(event))
61
      ) {
62
        if (1 === days.length) {
63
          throw new MaximumEventReachedException();
64
        }
65
66
        errors.push(date);
67
        continue;
68
      }
69
70
      savePromises.push(this.eventRepository.save(event));
71
    }
72
73
    await Promise.all(savePromises);
74
75
    return new AddEventsView(errors);
76
  }
77
78
  private getDays(startDate: Date, endDate: Date): Date[] {
79
    const days = this.dateUtils.getWorkedDaysDuringAPeriod(startDate, endDate);
80
81
    if (0 === days.length) {
82
      throw new NoDateDuringThisPeriodException();
83
    }
84
85
    return days;
86
  }
87
}
88